#include "Date.h"
#include <string>
Date Date::default_date = { 1970,1,1 };

void Date::set_default(int year, int month, int day) {
    default_date.y = year;
    default_date.m = month;
    default_date.d = day;

    if (!isvalid(year, month, day))
        throw Bad_date();
}

Date::Date(int yy, int mm, int dd) {
    y = yy ? yy : default_date.y;
    m = mm ? mm : default_date.m;
    d = dd ? dd : default_date.d;
    if (!isvalid(y, m, d))
        throw Bad_date();
}

std::string Date::string_rep() const
{
    std::string restr = std::to_string(y) + "." + std::to_string(m) + "." + std::to_string(d);
    return restr;
}

void Date::char_rep(char s[]) const
{
    std::string tmpstr = std::to_string(y) + "." + std::to_string(m) + "." + std::to_string(d);
    for (unsigned int i = 0; i < tmpstr.size(); i++)
        s[i] = tmpstr[i];
}

int Date::getDaysNum(int year,int month){
    bool isLeap = (year % 100 != 0 && year % 4 == 0) || (year % 400 == 0);
    static int days[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
    if(isLeap&&month==2) return 29;
    else return days[month-1];
}

Date& Date::add_year(int n)
{
    this->y += n;
    if (d > getDaysNum(y,m))d = getDaysNum(y,m);//检查日期超标
    return *this;
}

Date& Date::add_month(int n)
{
    this->y += (this->m+n)/12;
    if(this->m+n==12) this->y--;
    this->m = (this->m+n)%12;
    if(this->m==0) this->m=12;
    if (d > getDaysNum(y, m))d = getDaysNum(y, m);//检查日期超标
    return *this;
}

Date& Date::add_day(int n)
{
    for(int i =0;i<n;i++){
        this->d = (this->d+1)%getDaysNum(y,m);
        if (this->d == 0)this->d = getDaysNum(y, m);
        if(d==1) add_month(1);
    }//进行n次增加一天
    return *this;
}

bool Date::isvalid(int year, int month, int day)
{
    //仅支持1970年后
    if (year <1970 )return false;
    //月份
    if (month > 12 || month < 1)return false;
    //日期
    int maxDay = getDaysNum(year,month);
    if(day<1||day>maxDay) return false;
    return true;
}
